Prepare county level data

Overview of time windows

US prevalence: 03/09 - 04/18 US socdist: 03/01 - 05/03

UK prevalence: 03/09 - 04/10 UK socdist: 03/01 - 03/31

GER prevalence: 01/01 - 04/25 GER socdist: 02/25 - 04/27

Read and format prevalence data


df_us_covid <- read_csv('timeseries_usa_county_march1_april_09.csv')
df_us_covid$time %>% max()
[1] 40
df_us_covid <- df_us_covid %>% 
  filter(time <=31) %>% 
  arrange(countyfips) %>%
  mutate(stabil = -stabil) %>%
  dplyr::rename(county_fips = countyfips,
         pers_o = open, 
         pers_c = sci,
         pers_e = extra,
         pers_a = agree,
         pers_n = stabil)


df_us_covid <- df_us_covid %>% 
  dplyr::select(county_fips, time, mark, rate_day, pers_o,
                pers_c, pers_e, pers_a, pers_n)


df_us_covid %>% head()

Conty level controls


df_us_ctrl <- read.csv('controls_US.csv')

df_us_ctrl <- df_us_ctrl %>% select(-county_name) %>% 
  rename(county_fips = county)

df_us_ctrl %>% head()
NA

Social distancing data unacast


df_us_socdist <- read_csv('0409_sds-full-county.csv')

# create sequence of dates
date_sequence <- seq.Date(as.Date('2020-03-09'),
                          as.Date('2020-03-31'), 1)
                     

# create data frame with time sequence
df_dates = tibble(date_sequence, 1:length(date_sequence)) 
names(df_dates) <- c('date', 'time')

# merge day index with gps data
df_us_socdist = df_us_socdist %>% 
  merge(df_dates, by='date') %>% 
  arrange(county_fips) %>%
  as_tibble()

df_us_socdist %>% head()

Social distancing data FB


fb_files <- list.files('../FB Data/US individual files/Mobility/',
                       '*.csv', full.names = T)

df_us_socdist_fb <- fb_files %>% 
  map(read_csv) %>% bind_rows()

df_us_socdist_fb$ds %>% summary()
        Min.      1st Qu.       Median         Mean      3rd Qu.         Max. 
"2020-03-01" "2020-03-16" "2020-04-01" "2020-04-01" "2020-04-17" "2020-05-03" 
df_us_socdist_fb <- df_us_socdist_fb %>%
  select(-age_bracket, -gender, -baseline_name, -baseline_type) %>%
  rename(date = ds,
         county_fips = polygon_id,
         county_name = polygon_name,
         socdist_tiles = all_day_bing_tiles_visited_relative_change,
         socdist_single_tile = all_day_ratio_single_tile_users)

df_us_socdist_fb <- df_us_socdist_fb %>%
  filter(date >= '2020-03-09' & date <= '2020-03-31') %>%
  group_by(county_fips) %>% 
  arrange(date) %>% 
  mutate(time = row_number()) %>%
  ungroup() %>% 
  arrange(county_fips)

head(df_us_socdist_fb)

Sanity check socdist data

socdist <- df_us_socdist %>% merge(df_us_socdist_fb, by = c("county_fips", "time")) 

socdist[c('daily_distance_diff', 'daily_visitation_diff', 'socdist_tiles', 'socdist_single_tile')] %>% 
  cor(use = 'pairwise.complete')
                      daily_distance_diff daily_visitation_diff socdist_tiles socdist_single_tile
daily_distance_diff             1.0000000             0.1361318     0.3061683          -0.2746350
daily_visitation_diff           0.1361318             1.0000000     0.3826102          -0.3624062
socdist_tiles                   0.3061683             0.3826102     1.0000000          -0.7544123
socdist_single_tile            -0.2746350            -0.3624062    -0.7544123           1.0000000

Merge data


df_us <- plyr::join_all(list(df_us_covid, df_us_socdist_fb),
                  by = c('county_fips', 'time'), 
                  type = 'inner') %>% 
  plyr::join(df_us_ctrl, by='county_fips') %>% 
  arrange(county_fips, time)

# keep only counties with full data
fips_complete <- df_us %>% 
  group_by(county_fips) %>% 
  summarize(n = n()) %>% 
  filter(n==max(.$n)) %>% 
  .$county_fips

df_us <- df_us %>% filter(county_fips %in% fips_complete)

Explore data

Plot distributions


# distribution of observations per county
df_us %>% group_by(county_fips) %>% 
  summarise(mark = mean(mark)) %>% 
  ggplot(aes(x=mark)) + 
  geom_histogram(color="black", fill="white", binwidth = 300) +
  ggtitle('Distribution of observations per county')


  
# distributions of mean prevalence rates per county
df_us %>% group_by(county_fips) %>% 
  summarise(rate_day = mean(rate_day)) %>%
  ggplot(aes(x=rate_day)) + 
  geom_histogram(color="black", fill="white", binwidth = 0.01) +
  ggtitle('Distribution of mean prevalence rates by county')


  
# distribution of mean sd distance measue
df_us %>% group_by(county_fips) %>% 
  summarise(socdist_tiles = mean(socdist_tiles)) %>%
  ggplot(aes(x=socdist_tiles)) + 
  geom_histogram(color="black", fill="white", bins = 200) +
 ggtitle('Distribution of mean tiles visited measure by county')



# distribution of mean sd visit measue
df_us %>% group_by(county_fips) %>% 
  summarise(socdist_single_tile = mean(socdist_single_tile)) %>%
  ggplot(aes(x=socdist_single_tile)) + 
  geom_histogram(color="black", fill="white", bins = 200) +
  ggtitle('Distribution of mean single tile measute by county')

NA
NA

Plot prevalence over time


df_us %>% sample_n(20000) %>%
  ggplot(aes(x=time, y=rate_day)) + 
  geom_point(aes(col=county_name, size=mark)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall prevalence over time")



pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_us %>% mutate(prev_tail = cut(.[[i]], 
                                       breaks = c(-Inf, quantile(.[[i]], 0.05), quantile(.[[i]], 0.95), Inf),
                                       labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(prev_tail != 'center') %>%
  ggplot(aes(x=time, y=rate_day)) + 
  geom_point(aes(col=county_name, size=mark)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~prev_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Plot social distancing single tile visited


df_us %>% sample_n(10000) %>%
  ggplot(aes(x=time, y=socdist_single_tile)) + 
  geom_point(aes(col=county_name, size=mark)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall social distancing (single tile) over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_us %>% mutate(dist_tail = cut(.[[i]], 
                                       breaks = c(-Inf, quantile(.[[i]], 0.05), quantile(.[[i]], 0.95), Inf),
                                       labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(dist_tail != 'center') %>%
  ggplot(aes(x=time, y=socdist_single_tile)) + 
  geom_point(aes(col=county_name, size=mark)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~dist_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Control for weekend effect


df_us %>% sample_n(10000) %>%
  ggplot(aes(x=time, y=socdist_single_tile_clean)) + 
  geom_point(aes(col=county_name, size=mark)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall social distancing (single tile) over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_us %>% mutate(dist_tail = cut(.[[i]], 
                                       breaks = c(-Inf, quantile(.[[i]], 0.05), quantile(.[[i]], 0.95), Inf),
                                       labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(dist_tail != 'center') %>%
  ggplot(aes(x=time, y=socdist_single_tile_clean)) + 
  geom_point(aes(col=county_name, size=mark)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~dist_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Variance over time

Correlations


df_us %>% select(-time, -date, -county_name) %>% 
  group_by(county_fips) %>%
  summarize_if(is.numeric, mean) %>% 
  select(-county_fips) %>%
  cor(use='pairwise.complete.obs') %>% 
  round(3)
                      mark rate_day pers_o pers_c pers_e pers_a pers_n socdist_tiles socdist_single_tile
mark                 1.000    0.189  0.279 -0.052  0.097 -0.041 -0.174        -0.377               0.214
rate_day             0.189    1.000  0.196 -0.049  0.044 -0.037 -0.094        -0.240               0.167
pers_o               0.279    0.196  1.000 -0.052 -0.086 -0.154 -0.228        -0.249               0.208
pers_c              -0.052   -0.049 -0.052  1.000  0.148  0.650 -0.402         0.165              -0.258
pers_e               0.097    0.044 -0.086  0.148  1.000  0.235 -0.386        -0.065              -0.061
pers_a              -0.041   -0.037 -0.154  0.650  0.235  1.000 -0.384         0.123              -0.277
pers_n              -0.174   -0.094 -0.228 -0.402 -0.386 -0.384  1.000         0.062               0.190
socdist_tiles       -0.377   -0.240 -0.249  0.165 -0.065  0.123  0.062         1.000              -0.595
socdist_single_tile  0.214    0.167  0.208 -0.258 -0.061 -0.277  0.190        -0.595               1.000
airport_distance    -0.212   -0.055 -0.093 -0.094 -0.109 -0.103  0.040         0.258              -0.135
republican          -0.345   -0.234 -0.349 -0.046 -0.077 -0.086  0.307         0.350              -0.231
medage              -0.223   -0.075 -0.034 -0.066 -0.092 -0.074  0.232         0.013               0.301
male                -0.115   -0.052 -0.117 -0.096 -0.058 -0.154  0.054         0.126              -0.041
popdens              0.322    0.375  0.222 -0.044  0.028 -0.070 -0.044        -0.244               0.221
manufact            -0.162   -0.138 -0.386  0.070  0.034  0.119  0.179         0.057              -0.126
tourism              0.112    0.111  0.368  0.017 -0.003 -0.067 -0.188        -0.006               0.074
academics            0.418    0.284  0.462 -0.116  0.141 -0.145 -0.341        -0.434               0.259
medinc               0.307    0.228  0.226 -0.173  0.134 -0.219 -0.215        -0.444               0.225
physician_pc        -0.181   -0.100 -0.213  0.107 -0.047  0.112  0.117         0.163              -0.114
                    airport_distance republican medage   male popdens manufact tourism academics medinc
mark                          -0.212     -0.345 -0.223 -0.115   0.322   -0.162   0.112     0.418  0.307
rate_day                      -0.055     -0.234 -0.075 -0.052   0.375   -0.138   0.111     0.284  0.228
pers_o                        -0.093     -0.349 -0.034 -0.117   0.222   -0.386   0.368     0.462  0.226
pers_c                        -0.094     -0.046 -0.066 -0.096  -0.044    0.070   0.017    -0.116 -0.173
pers_e                        -0.109     -0.077 -0.092 -0.058   0.028    0.034  -0.003     0.141  0.134
pers_a                        -0.103     -0.086 -0.074 -0.154  -0.070    0.119  -0.067    -0.145 -0.219
pers_n                         0.040      0.307  0.232  0.054  -0.044    0.179  -0.188    -0.341 -0.215
socdist_tiles                  0.258      0.350  0.013  0.126  -0.244    0.057  -0.006    -0.434 -0.444
socdist_single_tile           -0.135     -0.231  0.301 -0.041   0.221   -0.126   0.074     0.259  0.225
airport_distance               1.000      0.121  0.029  0.194  -0.144   -0.138   0.101    -0.133 -0.177
republican                     0.121      1.000  0.134  0.162  -0.264    0.172  -0.220    -0.452 -0.192
medage                         0.029      0.134  1.000 -0.040  -0.105    0.091  -0.080    -0.210 -0.107
male                           0.194      0.162 -0.040  1.000  -0.101   -0.080  -0.046    -0.175 -0.004
popdens                       -0.144     -0.264 -0.105 -0.101   1.000   -0.120   0.049     0.242  0.154
manufact                      -0.138      0.172  0.091 -0.080  -0.120    1.000  -0.380    -0.385 -0.179
tourism                        0.101     -0.220 -0.080 -0.046   0.049   -0.380   1.000     0.279 -0.022
academics                     -0.133     -0.452 -0.210 -0.175   0.242   -0.385   0.279     1.000  0.719
medinc                        -0.177     -0.192 -0.107 -0.004   0.154   -0.179  -0.022     0.719  1.000
physician_pc                  -0.038      0.196  0.078  0.159  -0.079    0.157  -0.226    -0.369 -0.202
                    physician_pc
mark                      -0.181
rate_day                  -0.100
pers_o                    -0.213
pers_c                     0.107
pers_e                    -0.047
pers_a                     0.112
pers_n                     0.117
socdist_tiles              0.163
socdist_single_tile       -0.114
airport_distance          -0.038
republican                 0.196
medage                     0.078
male                       0.159
popdens                   -0.079
manufact                   0.157
tourism                   -0.226
academics                 -0.369
medinc                    -0.202
physician_pc               1.000
  

Model building

Prepare functions


# function calculates all relevant models
run_models <- function(y, lvl1_x, lvl2_x, lvl2_id, data, ctrls=F){

  # subset data
  data = data %>% 
    dplyr::select(all_of(y), all_of(lvl1_x), all_of(lvl2_x), all_of(lvl2_id), 
                  popdens, rate_day, all_of(y))
  data = data %>% 
    dplyr::rename(y = all_of(y),
           lvl1_x = all_of(lvl1_x),
           lvl2_x = all_of(lvl2_x),
           lvl2_id = all_of(lvl2_id)
           )
  
  # configure optimization procedure
  ctrl_config <- lmeControl(opt = 'optim', maxIter = 100, msMaxIter = 100)

  # baseline
  baseline <- lme(fixed = y ~ 1, random = ~ 1 | lvl2_id, 
                    data = data,
                    correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # random intercept fixed slope
  random_intercept <- lme(fixed = y ~ lvl1_x + lvl2_x, 
                          random = ~ 1 | lvl2_id,
                            data = data,
                            correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # random intercept random slope
  random_slope <- lme(fixed = y ~ lvl1_x + lvl2_x, 
                      random = ~ lvl1_x | lvl2_id, 
                        data = data,
                        correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # cross level interaction
  interaction <- lme(fixed = y ~ lvl1_x * lvl2_x, 
                     random = ~ lvl1_x | lvl2_id, 
                       data = data,
                       correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')
  
  # create list with results
  results <- list('baseline' = baseline, 
                  "random_intercept" = random_intercept, 
                  "random_slope" = random_slope,
                  "interaction" = interaction)
  
  
  if (ctrls == 'dem' | ctrls == 'prev'){
    
    # random intercept random slope
    random_slope_ctrl_dem <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens,
                              random = ~ lvl1_x | lvl2_id, 
                          data = data,
                          correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
    # cross level interaction
    interaction_ctrl_main_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
    # cross level interaction
    interaction_ctrl_int_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')        
    
    # create list with results
    results <- list('baseline' = baseline, 
                    "random_intercept" = random_intercept, 
                    "random_slope" = random_slope,
                    "interaction" = interaction,
                    "random_slope_ctrl_dem" = random_slope_ctrl_dem,
                    "interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
                    "interaction_ctrl_int_dem" = interaction_ctrl_int_dem)
  }
  
  if (ctrls == 'prev'){
  
    # random intercept random slope
    random_slope_ctrl_prev <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens + rate_day,
                              random = ~ lvl1_x + rate_day | lvl2_id, 
                          data = data,
                          correlation = corAR1(),
                          control = ctrl_config,
                  method = 'ML')  
    
        # cross level interaction
    interaction_ctrl_main_prev <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens + rate_day,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
  
    # cross level interaction
    interaction_ctrl_int_prev<- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens + rate_day,
                             random = ~ lvl1_x + rate_day | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                          control = ctrl_config,
                  method = 'ML')
  
    # create list with results
    results <- list('baseline' = baseline, 
                    "random_intercept" = random_intercept, 
                    "random_slope" = random_slope,
                    "interaction" = interaction,
                    "random_slope_ctrl_dem" = random_slope_ctrl_dem,
                    "interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
                    "interaction_ctrl_int_dem" = interaction_ctrl_int_dem,                    
                    "random_slope_ctrl_prev" = random_slope_ctrl_prev,
                    "interaction_ctrl_main_prev" = interaction_ctrl_main_prev,
                    "interaction_ctrl_int_prev" = interaction_ctrl_int_prev)
  }
  
  if(ctrls == 'exp'){
    # random intercept random slope
  random_slope_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) + lvl2_x, 
                      random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id, 
                        data = data,
                        correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # cross level interaction
  interaction_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) * lvl2_x, 
                     random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id, 
                       data = data,
                       correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')  
  
  
  # create list with results
  results <- list('baseline' = baseline, 
                  "random_intercept" = random_intercept, 
                  "random_slope" = random_slope,
                  "interaction" = interaction,                  
                  "random_slope_exp" = random_slope_exp,
                  "interaction_exp" = interaction_exp)
  }
  
  return(results)
        
}

# extracts table with coefficients and tests statistics
extract_results <- function(models) {
  
  models_summary <- models %>% 
  map(summary) %>% 
  map("tTable") %>% 
  map(as.data.frame) %>% 
  map(round, 10) 
  # %>% map(~ .[str_detect(rownames(.), 'Inter|lvl'),])
  
  return(models_summary)
  
}


compare_models <- function(models) {

  mdl_names <- models %>% names()
  
  str = ''
  for (i in mdl_names){
    
    mdl_str <- paste('models$', i, sep = '')
    
    if(i == 'baseline'){
      str <- mdl_str
    }else{
    str <- paste(str, mdl_str, sep=', ')
    }
  }
  
  anova_str <- paste0('anova(', str, ')')
  mdl_comp <- eval(parse(text=anova_str))
  rownames(mdl_comp) = mdl_names
  return(mdl_comp)
}

Rescale Data

Predict prevalence

prevalence ~ openness


models_o_covid <-run_models(y = 'rate_day',
                         lvl1_x = 'time',
                         lvl2_x = 'pers_o',
                         lvl2_id = 'county_fips',
                         data = df_us_scaled,
                         ctrls = 'dem')

extract_results(models_o_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_o_covid)
NA

prevalence ~ conscientiousness


models_c_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'dem')

extract_results(models_c_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_c_covid)
NA
NA

prevalence ~ extraversion


models_e_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'dem')

extract_results(models_e_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_e_covid)
NA
NA

prevalence ~ agreeableness


models_a_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'dem')

extract_results(models_a_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_a_covid)
NA
NA

prevalence ~ neuroticism


models_n_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'dem')

extract_results(models_n_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_n_covid)
NA
NA

Predict social distancing

social distancing ~ openness


models_o_sd <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_o', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'prev')

extract_results(models_o_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_o_sd)
NA
NA

social distancing ~ conscientiousness


models_c_sd <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'prev')

extract_results(models_c_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_c_sd)
NA
NA

social distancing ~ extraversion


models_e_sd <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'prev')

extract_results(models_e_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_e_sd)
NA
NA

social distancing ~ agreeableness


models_a_sd <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'prev')

extract_results(models_a_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_a_sd)
NA
NA

social distancing ~ neuroticism


models_n_sd <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'county_fips', 
                         data = df_us_scaled,
                         ctrls = 'prev')

extract_results(models_n_sd)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_n_sd)
NA

Create overview table

Define function to create overview tables


summary_table <- function(models, dv_name, prev=F){

  temp_df_ctrl_main <- NULL
  temp_df_ctrl_int <- NULL
  temp_df_ctrl_int_prev <- NULL
  
  for (i in models){
    results <- i %>% extract_results()
    
    results_ctrl_main <- results$interaction_ctrl_main_dem['lvl1_x:lvl2_x',]
    temp_df_ctrl_main <- temp_df_ctrl_main %>% rbind(results_ctrl_main)
    
    results_ctrl_int <- results$interaction_ctrl_int_dem['lvl1_x:lvl2_x',]
    temp_df_ctrl_int <- temp_df_ctrl_int %>% rbind(results_ctrl_int)
    
    if(prev){
      results_ctrl_int_prev <- results$interaction_ctrl_int_prev['lvl1_x:lvl2_x',]
      temp_df_ctrl_int_prev <- temp_df_ctrl_int_prev %>% rbind(results_ctrl_int_prev)
    }
        
  }
  
  names_ctrl_main <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens')
  rownames(temp_df_ctrl_main) <- names_ctrl_main

  names_ctrl_int <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time')
  rownames(temp_df_ctrl_int) <- names_ctrl_int

  if(prev){
    names_ctrl_int_prev <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time_prev')
    rownames(temp_df_ctrl_int_prev) <- names_ctrl_int_prev
    
    sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int, temp_df_ctrl_int_prev) %>% round(4)
  }else{
    sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int) %>% round(4)
  }


  
  return(sum_tab)

} 

Create overview tables

# prevalence
models_prev <- list(models_o_covid, 
                    models_c_covid, 
                    models_e_covid, 
                    models_a_covid, 
                    models_n_covid)

sum_tab_prev <- summary_table(models_prev, dv_name = 'prev')

write.table(sum_tab_prev, quote=F)
Value Std.Error DF t-value p-value
prev~o*time_crtl_popdens 0.0244 0.0027 53135 9.1918 0
prev~c*time_crtl_popdens -0.0061 0.0027 53135 -2.266 0.0235
prev~e*time_crtl_popdens 0.0055 0.0027 53135 2.0302 0.0423
prev~a*time_crtl_popdens -0.0042 0.0027 53135 -1.572 0.116
prev~n*time_crtl_popdens -0.0109 0.0027 53135 -4.0489 1e-04
prev~o*time_crtl_popdens*time 0.013 0.0025 53134 5.1452 0
prev~c*time_crtl_popdens*time -0.0037 0.0025 53134 -1.5004 0.1335
prev~e*time_crtl_popdens*time 0.004 0.0025 53134 1.6065 0.1082
prev~a*time_crtl_popdens*time -4e-04 0.0025 53134 -0.179 0.858
prev~n*time_crtl_popdens*time -0.0085 0.0025 53134 -3.4502 6e-04
# social distancing
models_socdist <- list(models_o_sd, 
                       models_c_sd, 
                       models_e_sd, 
                       models_a_sd, 
                       models_n_sd)

sum_tab_socdist <- summary_table(models_socdist, dv_name = 'socdist', prev=T)

write.table(sum_tab_socdist, quote=F)
Value Std.Error DF t-value p-value
socdist~o*time_crtl_popdens 0.012 7e-04 53135 18.0098 0
socdist~c*time_crtl_popdens -0.006 7e-04 53135 -8.6385 0
socdist~e*time_crtl_popdens 0.0025 7e-04 53135 3.5181 4e-04
socdist~a*time_crtl_popdens -0.0067 7e-04 53135 -9.7575 0
socdist~n*time_crtl_popdens -0.0033 7e-04 53135 -4.5664 0
socdist~o*time_crtl_popdens*time 0.0099 7e-04 53134 14.8225 0
socdist~c*time_crtl_popdens*time -0.0055 7e-04 53134 -8.2817 0
socdist~e*time_crtl_popdens*time 0.0021 7e-04 53134 3.2025 0.0014
socdist~a*time_crtl_popdens*time -0.006 7e-04 53134 -9.0111 0
socdist~n*time_crtl_popdens*time -0.0028 7e-04 53134 -4.0934 0
socdist~o*time_crtl_popdens*time_prev 0.0102 7e-04 53133 15.0292 0
socdist~c*time_crtl_popdens*time_prev -0.0054 7e-04 53133 -8.1668 0
socdist~e*time_crtl_popdens*time_prev 0.0022 7e-04 53133 3.2724 0.0011
socdist~a*time_crtl_popdens*time_prev -0.0059 7e-04 53133 -8.8441 0
socdist~n*time_crtl_popdens*time_prev -0.0031 7e-04 53133 -4.5123 0

Conditional random forest analysis

Extract slopes


# slope prevalence
df_us_slope_prev <- df_us_scaled %>% split(.$county) %>% 
  map(~ lm(rate_day ~ time, data = .)) %>%
  map(coef) %>% 
  map_dbl('time') %>% 
  as.data.frame() %>% 
  rownames_to_column('county_fips') %>% 
  rename(slope_prev = '.')

df_us_slope_prev <- df_us_scaled %>% select(-time, -rate_day, -socdist_single_tile) %>%
  distinct() %>% 
  mutate(county_fips = as.character(county_fips)) %>%
  inner_join(df_us_slope_prev, by = 'county_fips') %>%
  drop_na()



# slope social distancing
df_us_slope_socdist <- df_us_scaled %>% split(.$county) %>% 
  map(~ lm(socdist_single_tile ~ time, data = .)) %>%
  map(coef) %>% 
  map_dbl('time') %>% 
  as.data.frame() %>% 
  rownames_to_column('county_fips') %>% 
  rename(slope_socdist = '.')

df_us_slope_socdist <- df_us_scaled %>% select(-time, -rate_day, -socdist_single_tile) %>%
  distinct() %>% 
  mutate(county_fips = as.character(county_fips)) %>%
  inner_join(df_us_slope_socdist, by = 'county_fips') %>%
  drop_na()

df_us_slope_socdist

Explore distribution of slopes

df_us_slope_prev %>% ggplot(aes(slope_prev)) + geom_histogram(bins = 100)


df_us_slope_socdist %>% ggplot(aes(slope_socdist)) + geom_histogram(bins = 100)

CRF prevalence ~ openness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_o_fit_prev <- cforest(slope_prev ~ pers_o + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_o_varimp_prev <- varimp(crf_o_fit_prev, nperm = 1)
crf_o_varimp_cond_prev <- varimp(crf_o_fit_prev, conditional = T, nperm = 1)

crf_o_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_o_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') +
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ conscientiousness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_c_fit_prev <- cforest(slope_prev ~ pers_c + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_c_varimp_prev <- varimp(crf_c_fit_prev, nperm = 1)
crf_c_varimp_cond_prev <- varimp(crf_c_fit_prev, conditional = T, nperm = 1)

crf_c_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_c_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ extraversion


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_e_fit_prev <- cforest(slope_prev ~ pers_e + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_e_varimp_prev <- varimp(crf_e_fit_prev, nperm = 1)
crf_e_varimp_cond_prev <- varimp(crf_e_fit_prev, conditional = T, nperm = 1)

crf_e_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_e_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ agreeableness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_a_fit_prev <- cforest(slope_prev ~ pers_a + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_a_varimp_prev <- varimp(crf_a_fit_prev, nperm = 1)
crf_a_varimp_cond_prev <- varimp(crf_a_fit_prev, conditional = T, nperm = 1)

crf_a_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_a_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ neuroticism


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_n_fit_prev <- cforest(slope_prev ~ pers_n + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_prev[-1], 
                         controls = ctrls)

crf_n_varimp_prev <- varimp(crf_n_fit_prev, nperm = 1)
crf_n_varimp_cond_prev <- varimp(crf_n_fit_prev, conditional = T, nperm = 1)

crf_n_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_n_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ openness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_o_fit_socdist <- cforest(slope_socdist ~ pers_o + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_o_varimp_socdist <- varimp(crf_o_fit_socdist, nperm = 1)
crf_o_varimp_cond_socdist <- varimp(crf_o_fit_socdist, conditional = T, nperm = 1)

crf_o_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_o_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ conscientiousness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_c_fit_socdist <- cforest(slope_socdist ~ pers_c + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_c_varimp_socdist <- varimp(crf_c_fit_socdist, nperm = 1)
crf_c_varimp_cond_socdist <- varimp(crf_c_fit_socdist, conditional = T, nperm = 1)

crf_c_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_c_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ extraversion


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_e_fit_socdist <- cforest(slope_socdist ~ pers_e + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_e_varimp_socdist <- varimp(crf_e_fit_socdist, nperm = 1)
crf_e_varimp_cond_socdist <- varimp(crf_e_fit_socdist, conditional = T, nperm = 1)

crf_e_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_e_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ agreeableness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_a_fit_socdist <- cforest(slope_socdist ~ pers_a + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_a_varimp_socdist <- varimp(crf_a_fit_socdist, nperm = 1)
crf_a_varimp_cond_socdist <- varimp(crf_a_fit_socdist, conditional = T, nperm = 1)

crf_a_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_a_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ neuroticism


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_n_fit_socdist <- cforest(slope_socdist ~ pers_n + airport_distance + republican +
                          medage + male + popdens + manufact +
                          tourism + academics + medinc + physician_pc, 
                         df_us_slope_socdist[-1], 
                         controls = ctrls)

crf_n_varimp_socdist <- varimp(crf_n_fit_socdist, nperm = 1)
crf_n_varimp_cond_socdist <- varimp(crf_n_fit_socdist, conditional = T, nperm = 1)

crf_n_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_n_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

Linear models predicting slopes from personality


lm_slope_prev_pers <- lm(slope_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n, 
                         data = df_us_slope_prev)
lm_slope_prev_pers %>% summary()

Call:
lm(formula = slope_prev ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_slope_prev)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.11019 -0.02930 -0.01466  0.00224  1.64943 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.027854   0.001886  14.769  < 2e-16 ***
pers_o       0.017433   0.002045   8.525  < 2e-16 ***
pers_c      -0.006911   0.002553  -2.707  0.00683 ** 
pers_e       0.004472   0.002094   2.135  0.03282 *  
pers_a       0.000545   0.002601   0.210  0.83404    
pers_n      -0.005611   0.002374  -2.363  0.01819 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.09289 on 2420 degrees of freedom
Multiple R-squared:  0.04663,   Adjusted R-squared:  0.04466 
F-statistic: 23.67 on 5 and 2420 DF,  p-value: < 2.2e-16
lm_slope_socdist_pers <- lm(slope_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n, 
                            data = df_us_slope_socdist)
lm_slope_socdist_pers %>% summary()

Call:
lm(formula = slope_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_slope_socdist)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.28392 -0.02426 -0.00637  0.01813  1.65694 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.104604   0.001132  92.426  < 2e-16 ***
pers_o       0.008687   0.001227   7.079 1.89e-12 ***
pers_c      -0.004476   0.001532  -2.922 0.003512 ** 
pers_e       0.003246   0.001257   2.583 0.009841 ** 
pers_a      -0.003405   0.001561  -2.181 0.029245 *  
pers_n      -0.004956   0.001425  -3.479 0.000513 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05574 on 2420 degrees of freedom
Multiple R-squared:  0.04961,   Adjusted R-squared:  0.04764 
F-statistic: 25.26 on 5 and 2420 DF,  p-value: < 2.2e-16

Linear models predicting slopes with controls


lm_slope_prev_pers <- lm(slope_prev ~ pers_o + pers_c + pers_e + pers_a + pers_n + 
                           airport_distance + republican + medage + male + popdens + 
                           manufact + tourism + academics + medinc + physician_pc,
                         data = df_us_slope_prev)
lm_slope_prev_pers %>% summary()

Call:
lm(formula = slope_prev ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_slope_prev)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.31430 -0.02291 -0.00994  0.00277  1.59045 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)       2.790e-02  1.713e-03  16.285  < 2e-16 ***
pers_o            2.761e-03  2.187e-03   1.263 0.206874    
pers_c           -3.284e-03  2.360e-03  -1.391 0.164245    
pers_e            1.138e-03  1.932e-03   0.589 0.555932    
pers_a            5.501e-03  2.476e-03   2.221 0.026416 *  
pers_n            2.122e-03  2.359e-03   0.900 0.368348    
airport_distance  2.754e-03  1.865e-03   1.477 0.139782    
republican       -7.602e-03  2.085e-03  -3.646 0.000272 ***
medage           -6.650e-05  1.807e-03  -0.037 0.970654    
male             -2.818e-05  1.876e-03  -0.015 0.988018    
popdens           3.369e-02  1.832e-03  18.395  < 2e-16 ***
manufact         -2.120e-03  2.059e-03  -1.030 0.303341    
tourism           5.024e-03  2.081e-03   2.414 0.015849 *  
academics         4.209e-03  3.415e-03   1.232 0.217913    
medinc            1.237e-02  2.824e-03   4.379 1.24e-05 ***
physician_pc      6.768e-04  1.889e-03   0.358 0.720186    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.08439 on 2410 degrees of freedom
Multiple R-squared:  0.2164,    Adjusted R-squared:  0.2115 
F-statistic: 44.37 on 15 and 2410 DF,  p-value: < 2.2e-16
lm_slope_socdist_pers <- lm(slope_socdist ~ pers_o + pers_c + pers_e + pers_a + pers_n + 
                              airport_distance + republican + medage + male + popdens + 
                              manufact + tourism + academics + medinc + physician_pc,
                            data = df_us_slope_socdist)
lm_slope_socdist_pers %>% summary()

Call:
lm(formula = slope_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_slope_socdist)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26752 -0.01730 -0.00324  0.01248  1.63123 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)       0.1046597  0.0010362 101.000  < 2e-16 ***
pers_o           -0.0003449  0.0013227  -0.261 0.794320    
pers_c           -0.0010022  0.0014272  -0.702 0.482618    
pers_e            0.0004776  0.0011681   0.409 0.682670    
pers_a            0.0007837  0.0014976   0.523 0.600800    
pers_n            0.0023991  0.0014266   1.682 0.092753 .  
airport_distance -0.0037722  0.0011277  -3.345 0.000835 ***
republican       -0.0109897  0.0012610  -8.715  < 2e-16 ***
medage            0.0058495  0.0010931   5.351 9.55e-08 ***
male              0.0053010  0.0011348   4.671 3.16e-06 ***
popdens           0.0055870  0.0011077   5.044 4.91e-07 ***
manufact          0.0023425  0.0012451   1.881 0.060040 .  
tourism           0.0039623  0.0012585   3.148 0.001662 ** 
academics         0.0056901  0.0020653   2.755 0.005912 ** 
medinc            0.0131087  0.0017081   7.675 2.39e-14 ***
physician_pc     -0.0029367  0.0011424  -2.570 0.010215 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05104 on 2410 degrees of freedom
Multiple R-squared:  0.2067,    Adjusted R-squared:  0.2017 
F-statistic: 41.85 on 15 and 2410 DF,  p-value: < 2.2e-16
gg <- gg + geom_map(data=us_map_shape, map=us_map_shape,
                    aes(x = x, y = y, map_id=fips),
                    color="black", fill="white", size=0.25)
Error: `map` must have the columns `x`, `y`, and `id`
df_us_covid %>% filter(county == 23013)

Change point analysis

library(changepoint)
Successfully loaded changepoint package version 2.2.2
 NOTE: Predefined penalty values changed in version 2.2.  Previous penalty values with a postfix 1 i.e. SIC1 are now without i.e. SIC and previous penalties without a postfix i.e. SIC are now with a postfix 0 i.e. SIC0. See NEWS and help files for further details.

Preparation

# keep only counties with full data
fips_complete <- df_us_scaled %>% 
  group_by(county_fips) %>% 
  summarize(n = n()) %>% 
  filter(n==max(.$n)) %>% 
  .$county_fips

Prevalence


# run changepoint analysis
df_us_prev_cpt_results <- df_us_scaled %>% select(county_fips, rate_day) %>%
  filter(county_fips %in% fips_complete) %>% 
  split(.$county_fips) %>%
  map(~ cpt.meanvar(as.vector(.$rate_day),
                    class=TRUE,
                    param.estimates=TRUE,
                    Q=1))

# calculate change point
df_us_prev_cpt_day <- df_us_prev_cpt_results %>% 
  map(cpts) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(cpt_day_prev = '.') %>%
  rownames_to_column('county_fips')

# calculate mean differences
df_us_prev_cpt_mean_diff <- df_us_prev_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$mean) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(mean_diff_prev = '.') %>%
  rownames_to_column('county_fips')

# calculate varaince differences
df_us_prev_cpt_var_diff <- df_us_prev_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$variance) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(var_diff_prev = '.') %>%
  rownames_to_column('county_fips')

# merge new variables 
df_us_cpt_prev <- df_us_scaled %>%
  select(-time, -rate_day, -socdist_single_tile, -socdist_single_tile_clean) %>%
  distinct() %>%
  mutate(county_fips = as.character(county_fips)) %>%
  left_join(df_us_prev_cpt_day, by='county_fips') %>%
  left_join(df_us_prev_cpt_mean_diff, by='county_fips') %>%
  left_join(df_us_prev_cpt_var_diff, by='county_fips')

df_us_cpt_prev %>% select(cpt_day_prev) %>% map(hist)
$cpt_day_prev
$breaks
 [1]  2  4  6  8 10 12 14 16 18 20 22

$counts
 [1]  10  32 148   4 189 674   9   7  10  78

$density
 [1] 0.004306632 0.013781223 0.063738157 0.001722653 0.081395349 0.290267011 0.003875969 0.003014643
 [9] 0.004306632 0.033591731

$mids
 [1]  3  5  7  9 11 13 15 17 19 21

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% select(mean_diff_prev) %>% map(hist)
$mean_diff_prev
$breaks
 [1]  0  2  4  6  8 10 12 14 16 18 20 22 24 26

$counts
 [1] 1106   34    7    5    2    3    3    0    0    0    0    0    1

$density
 [1] 0.4763135228 0.0146425495 0.0030146425 0.0021533161 0.0008613264 0.0012919897 0.0012919897
 [8] 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0004306632

$mids
 [1]  1  3  5  7  9 11 13 15 17 19 21 23 25

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% select(var_diff_prev) %>% map(hist)
$var_diff_prev
$breaks
 [1] -20   0  20  40  60  80 100 120 140 160 180 200 220 240 260 280 300

$counts
 [1]   59 1007    4    0    3    4    6    0    0    0    0    0    0    0    0    1

$density
 [1] 2.721402e-03 4.644834e-02 1.845018e-04 0.000000e+00 1.383764e-04 1.845018e-04 2.767528e-04
 [8] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
[15] 0.000000e+00 4.612546e-05

$mids
 [1] -10  10  30  50  70  90 110 130 150 170 190 210 230 250 270 290

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev %>% dim()
[1] 2397   19
df_us_cpt_prev %>% drop_na() %>% dim()
[1] 1080   19

for(i in head(df_us_prev_cpt_results,18)){
  plot(i)
}

NA

Socdist


# run changepoint analysis
df_us_socdist_cpt_results <- df_us_scaled %>% select(county_fips, socdist_single_tile_clean) %>%
  filter(county_fips %in% fips_complete) %>% 
  split(.$county_fips) %>%
  map(~ cpt.meanvar(as.vector(.$socdist_single_tile_clean),
                    #penalty = 'Asymptotic',
                    class=TRUE,
                    param.estimates=TRUE,
                    Q=1,
                    test.stat = 'Normal'))

# calculate change point
df_us_socdist_cpt_day <- df_us_socdist_cpt_results %>% 
  map(cpts) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(cpt_day_socdist = '.') %>%
  rownames_to_column('county_fips')

# calculate mean differences
df_us_socdist_cpt_mean_diff <- df_us_socdist_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$mean) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(mean_diff_socdist = '.') %>%
  rownames_to_column('county_fips')

# calculate varaince differences
df_us_socdist_cpt_var_diff <- df_us_socdist_cpt_results %>% 
  map(param.est) %>% 
  map(~ .$variance) %>% 
  map(~ .[2]-.[1]) %>% 
  unlist() %>% 
  as.data.frame() %>% 
  rename(var_diff_socdist = '.') %>%
  rownames_to_column('county_fips')

# merge new variables 
df_us_cpt_prev_socdist <- df_us_cpt_prev %>%
  left_join(df_us_socdist_cpt_day, by='county_fips') %>%
  left_join(df_us_socdist_cpt_mean_diff, by='county_fips') %>%
  left_join(df_us_socdist_cpt_var_diff, by='county_fips')

df_us_cpt_prev_socdist %>% select(cpt_day_socdist) %>% map(hist)
$cpt_day_socdist
$breaks
 [1]  2  4  6  8 10 12 14 16 18 20 22

$counts
 [1]  11 116 564 592 591  76 106  12   2 327

$density
 [1] 0.0022945348 0.0241969128 0.1176470588 0.1234876929 0.1232790989 0.0158531498 0.0221109720
 [8] 0.0025031289 0.0004171882 0.0682102628

$mids
 [1]  3  5  7  9 11 13 15 17 19 21

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% select(mean_diff_socdist) %>% map(hist)
$mean_diff_socdist
$breaks
 [1] -0.5  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0

$counts
 [1]    6   42  337 1043  667  236   53    8    3    1    1

$density
 [1] 0.0050062578 0.0350438048 0.2811848144 0.8702544848 0.5565289946 0.1969128077 0.0442219441
 [8] 0.0066750104 0.0025031289 0.0008343763 0.0008343763

$mids
 [1] -0.25  0.25  0.75  1.25  1.75  2.25  2.75  3.25  3.75  4.25  4.75

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% select(var_diff_socdist) %>% map(hist)
$var_diff_socdist
$breaks
 [1] -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2  0.0  0.2  0.4  0.6  0.8  1.0  1.2  1.4  1.6  1.8

$counts
 [1]   2   4  10  24  77 171 757 762 163  52  14  22  10   1   2   1

$density
 [1] 0.004826255 0.009652510 0.024131274 0.057915058 0.185810811 0.412644788 1.826737452 1.838803089
 [9] 0.393339768 0.125482625 0.033783784 0.053088803 0.024131274 0.002413127 0.004826255 0.002413127

$mids
 [1] -1.3 -1.1 -0.9 -0.7 -0.5 -0.3 -0.1  0.1  0.3  0.5  0.7  0.9  1.1  1.3  1.5  1.7

$xname
[1] ".x[[i]]"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"

df_us_cpt_prev_socdist %>% dim()
[1] 2397   22
df_us_cpt_prev_socdist %>% drop_na() %>% dim()
[1] 999  22

for(i in head(df_us_socdist_cpt_results,18)){
  plot(i)
}

NA

Predicting change points

Linear models predicting change points (no controls)

lm_cpt_socdist_pers %>% summary()

Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_us_cpt_prev_socdist)

Residuals:
   Min     1Q Median     3Q    Max 
-9.284 -3.119 -1.269  1.149 12.870 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 11.48853    0.09662 118.902  < 2e-16 ***
pers_o      -0.26056    0.10496  -2.483 0.013112 *  
pers_c       0.15915    0.13093   1.216 0.224291    
pers_e      -0.35704    0.10756  -3.319 0.000915 ***
pers_a       0.61317    0.13367   4.587 4.72e-06 ***
pers_n       0.14504    0.12217   1.187 0.235243    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.731 on 2391 degrees of freedom
Multiple R-squared:  0.02744,   Adjusted R-squared:  0.02541 
F-statistic: 13.49 on 5 and 2391 DF,  p-value: 5.281e-13

Linear models predicting change points with controls

lm_cpt_socdist_pers %>% summary()

Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + airport_distance + republican + medage + male + 
    popdens + manufact + tourism + academics + medinc + physician_pc, 
    data = df_us_cpt_prev_socdist)

Residuals:
   Min     1Q Median     3Q    Max 
-9.784 -3.111 -1.220  1.563 12.148 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)      11.476908   0.094787 121.080  < 2e-16 ***
pers_o            0.083785   0.121134   0.692  0.48921    
pers_c           -0.008695   0.130595  -0.067  0.94692    
pers_e           -0.256051   0.107138  -2.390  0.01693 *  
pers_a            0.415986   0.137692   3.021  0.00255 ** 
pers_n           -0.314164   0.131217  -2.394  0.01673 *  
airport_distance  0.077067   0.102536   0.752  0.45236    
republican        0.533550   0.115417   4.623 3.99e-06 ***
medage            0.156947   0.100341   1.564  0.11792    
male              0.017010   0.104308   0.163  0.87047    
popdens           0.158159   0.101480   1.559  0.11924    
manufact          0.077820   0.114000   0.683  0.49490    
tourism          -0.280650   0.114817  -2.444  0.01458 *  
academics         0.066161   0.189260   0.350  0.72669    
medinc           -0.873767   0.156588  -5.580 2.68e-08 ***
physician_pc      0.139214   0.104699   1.330  0.18376    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.636 on 2376 degrees of freedom
  (5 observations deleted due to missingness)
Multiple R-squared:  0.07064,   Adjusted R-squared:  0.06477 
F-statistic: 12.04 on 15 and 2376 DF,  p-value: < 2.2e-16
LS0tCnRpdGxlOiAiQ09WSUQtMTkgVVMiCmF1dGhvcjogIkhlaW5yaWNoIFBldGVycyIKZGF0ZTogIjQvMTUvMjAyMCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCiMgTUFDCiBrbml0cjo6b3B0c19rbml0JHNldChyb290LmRpciA9ICcvVXNlcnMvaHAyNTAwL0dvb2dsZSBEcml2ZS9TVFVEWS9Db2x1bWJpYS9SZXNlYXJjaC9Db3JvbmEvRGF0YS9VUycpCgpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KG5sbWUpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGFydHkpCmxpYnJhcnkoZG9QYXJhbGxlbCkKCmBgYAoKCiMgUHJlcGFyZSBjb3VudHkgbGV2ZWwgZGF0YSAKCiMjIyBPdmVydmlldyBvZiB0aW1lIHdpbmRvd3MKVVMgcHJldmFsZW5jZTogMDMvMDkgLSAwNC8xOApVUyBzb2NkaXN0OiAwMy8wMSAtIDA1LzAzCgpVSyBwcmV2YWxlbmNlOiAwMy8wOSAtIDA0LzEwClVLIHNvY2Rpc3Q6IDAzLzAxIC0gMDMvMzEKCkdFUiBwcmV2YWxlbmNlOiAwMS8wMSAtIDA0LzI1CkdFUiBzb2NkaXN0OiAwMi8yNSAtIDA0LzI3CgojIyMgUmVhZCBhbmQgZm9ybWF0IHByZXZhbGVuY2UgZGF0YSAKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgpkZl91c19jb3ZpZCA8LSByZWFkX2NzdigndGltZXNlcmllc191c2FfY291bnR5X21hcmNoMV9hcHJpbF8wOS5jc3YnKQpkZl91c19jb3ZpZCR0aW1lICU+JSBtYXgoKQoKZGZfdXNfY292aWQgPC0gZGZfdXNfY292aWQgJT4lIAogIGZpbHRlcih0aW1lIDw9MzEpICU+JSAKICBhcnJhbmdlKGNvdW50eWZpcHMpICU+JQogIG11dGF0ZShzdGFiaWwgPSAtc3RhYmlsKSAlPiUKICBkcGx5cjo6cmVuYW1lKGNvdW50eV9maXBzID0gY291bnR5ZmlwcywKICAgICAgICAgcGVyc19vID0gb3BlbiwgCiAgICAgICAgIHBlcnNfYyA9IHNjaSwKICAgICAgICAgcGVyc19lID0gZXh0cmEsCiAgICAgICAgIHBlcnNfYSA9IGFncmVlLAogICAgICAgICBwZXJzX24gPSBzdGFiaWwpCgoKZGZfdXNfY292aWQgPC0gZGZfdXNfY292aWQgJT4lIAogIGRwbHlyOjpzZWxlY3QoY291bnR5X2ZpcHMsIHRpbWUsIG1hcmssIHJhdGVfZGF5LCBwZXJzX28sCiAgICAgICAgICAgICAgICBwZXJzX2MsIHBlcnNfZSwgcGVyc19hLCBwZXJzX24pCgoKZGZfdXNfY292aWQgJT4lIGhlYWQoKQpgYGAKCiMjIyBDb250eSBsZXZlbCBjb250cm9scyAKYGBge3J9CgpkZl91c19jdHJsIDwtIHJlYWQuY3N2KCdjb250cm9sc19VUy5jc3YnKQoKZGZfdXNfY3RybCA8LSBkZl91c19jdHJsICU+JSBzZWxlY3QoLWNvdW50eV9uYW1lKSAlPiUgCiAgcmVuYW1lKGNvdW50eV9maXBzID0gY291bnR5KQoKZGZfdXNfY3RybCAlPiUgaGVhZCgpCgpgYGAKCgojIyMgU29jaWFsIGRpc3RhbmNpbmcgZGF0YSB1bmFjYXN0CmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKZGZfdXNfc29jZGlzdCA8LSByZWFkX2NzdignMDQwOV9zZHMtZnVsbC1jb3VudHkuY3N2JykKCiMgY3JlYXRlIHNlcXVlbmNlIG9mIGRhdGVzCmRhdGVfc2VxdWVuY2UgPC0gc2VxLkRhdGUoYXMuRGF0ZSgnMjAyMC0wMy0wOScpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFzLkRhdGUoJzIwMjAtMDMtMzEnKSwgMSkKICAgICAgICAgICAgICAgICAgICAgCgojIGNyZWF0ZSBkYXRhIGZyYW1lIHdpdGggdGltZSBzZXF1ZW5jZQpkZl9kYXRlcyA9IHRpYmJsZShkYXRlX3NlcXVlbmNlLCAxOmxlbmd0aChkYXRlX3NlcXVlbmNlKSkgCm5hbWVzKGRmX2RhdGVzKSA8LSBjKCdkYXRlJywgJ3RpbWUnKQoKIyBtZXJnZSBkYXkgaW5kZXggd2l0aCBncHMgZGF0YQpkZl91c19zb2NkaXN0ID0gZGZfdXNfc29jZGlzdCAlPiUgCiAgbWVyZ2UoZGZfZGF0ZXMsIGJ5PSdkYXRlJykgJT4lIAogIGFycmFuZ2UoY291bnR5X2ZpcHMpICU+JQogIGFzX3RpYmJsZSgpCgpkZl91c19zb2NkaXN0ICU+JSBoZWFkKCkKYGBgCgoKIyMjIFNvY2lhbCBkaXN0YW5jaW5nIGRhdGEgRkIKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgpmYl9maWxlcyA8LSBsaXN0LmZpbGVzKCcuLi9GQiBEYXRhL1VTIGluZGl2aWR1YWwgZmlsZXMvTW9iaWxpdHkvJywKICAgICAgICAgICAgICAgICAgICAgICAnKi5jc3YnLCBmdWxsLm5hbWVzID0gVCkKCmRmX3VzX3NvY2Rpc3RfZmIgPC0gZmJfZmlsZXMgJT4lIAogIG1hcChyZWFkX2NzdikgJT4lIGJpbmRfcm93cygpCgpkZl91c19zb2NkaXN0X2ZiJGRzICU+JSBzdW1tYXJ5KCkKCmRmX3VzX3NvY2Rpc3RfZmIgPC0gZGZfdXNfc29jZGlzdF9mYiAlPiUKICBzZWxlY3QoLWFnZV9icmFja2V0LCAtZ2VuZGVyLCAtYmFzZWxpbmVfbmFtZSwgLWJhc2VsaW5lX3R5cGUpICU+JQogIHJlbmFtZShkYXRlID0gZHMsCiAgICAgICAgIGNvdW50eV9maXBzID0gcG9seWdvbl9pZCwKICAgICAgICAgY291bnR5X25hbWUgPSBwb2x5Z29uX25hbWUsCiAgICAgICAgIHNvY2Rpc3RfdGlsZXMgPSBhbGxfZGF5X2JpbmdfdGlsZXNfdmlzaXRlZF9yZWxhdGl2ZV9jaGFuZ2UsCiAgICAgICAgIHNvY2Rpc3Rfc2luZ2xlX3RpbGUgPSBhbGxfZGF5X3JhdGlvX3NpbmdsZV90aWxlX3VzZXJzKQoKZGZfdXNfc29jZGlzdF9mYiA8LSBkZl91c19zb2NkaXN0X2ZiICU+JQogIGZpbHRlcihkYXRlID49ICcyMDIwLTAzLTA5JyAmIGRhdGUgPD0gJzIwMjAtMDMtMzEnKSAlPiUKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIGFycmFuZ2UoZGF0ZSkgJT4lIAogIG11dGF0ZSh0aW1lID0gcm93X251bWJlcigpKSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGFycmFuZ2UoY291bnR5X2ZpcHMpCgpoZWFkKGRmX3VzX3NvY2Rpc3RfZmIpCmBgYAoKIyMjIFNhbml0eSBjaGVjayBzb2NkaXN0IGRhdGEKYGBge3J9CnNvY2Rpc3QgPC0gZGZfdXNfc29jZGlzdCAlPiUgbWVyZ2UoZGZfdXNfc29jZGlzdF9mYiwgYnkgPSBjKCJjb3VudHlfZmlwcyIsICJ0aW1lIikpIAoKc29jZGlzdFtjKCdkYWlseV9kaXN0YW5jZV9kaWZmJywgJ2RhaWx5X3Zpc2l0YXRpb25fZGlmZicsICdzb2NkaXN0X3RpbGVzJywgJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnKV0gJT4lIAogIGNvcih1c2UgPSAncGFpcndpc2UuY29tcGxldGUnKQoKYGBgCgoKIyMjIE1lcmdlIGRhdGEKYGBge3J9CgpkZl91cyA8LSBwbHlyOjpqb2luX2FsbChsaXN0KGRmX3VzX2NvdmlkLCBkZl91c19zb2NkaXN0X2ZiKSwKICAgICAgICAgICAgICAgICAgYnkgPSBjKCdjb3VudHlfZmlwcycsICd0aW1lJyksIAogICAgICAgICAgICAgICAgICB0eXBlID0gJ2lubmVyJykgJT4lIAogIHBseXI6OmpvaW4oZGZfdXNfY3RybCwgYnk9J2NvdW50eV9maXBzJykgJT4lIAogIGFycmFuZ2UoY291bnR5X2ZpcHMsIHRpbWUpCgojIGtlZXAgb25seSBjb3VudGllcyB3aXRoIGZ1bGwgZGF0YQpmaXBzX2NvbXBsZXRlIDwtIGRmX3VzICU+JSAKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIHN1bW1hcml6ZShuID0gbigpKSAlPiUgCiAgZmlsdGVyKG49PW1heCguJG4pKSAlPiUgCiAgLiRjb3VudHlfZmlwcwoKZGZfdXMgPC0gZGZfdXMgJT4lIGZpbHRlcihjb3VudHlfZmlwcyAlaW4lIGZpcHNfY29tcGxldGUpCgpgYGAKCiMjIEV4cGxvcmUgZGF0YQojIyMgUGxvdCBkaXN0cmlidXRpb25zCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQoKIyBkaXN0cmlidXRpb24gb2Ygb2JzZXJ2YXRpb25zIHBlciBjb3VudHkKZGZfdXMgJT4lIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXNlKG1hcmsgPSBtZWFuKG1hcmspKSAlPiUgCiAgZ2dwbG90KGFlcyh4PW1hcmspKSArIAogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJibGFjayIsIGZpbGw9IndoaXRlIiwgYmlud2lkdGggPSAzMDApICsKICBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2Ygb2JzZXJ2YXRpb25zIHBlciBjb3VudHknKQoKICAKIyBkaXN0cmlidXRpb25zIG9mIG1lYW4gcHJldmFsZW5jZSByYXRlcyBwZXIgY291bnR5CmRmX3VzICU+JSBncm91cF9ieShjb3VudHlfZmlwcykgJT4lIAogIHN1bW1hcmlzZShyYXRlX2RheSA9IG1lYW4ocmF0ZV9kYXkpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9cmF0ZV9kYXkpKSArIAogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJibGFjayIsIGZpbGw9IndoaXRlIiwgYmlud2lkdGggPSAwLjAxKSArCiAgZ2d0aXRsZSgnRGlzdHJpYnV0aW9uIG9mIG1lYW4gcHJldmFsZW5jZSByYXRlcyBieSBjb3VudHknKQoKICAKIyBkaXN0cmlidXRpb24gb2YgbWVhbiBzZCBkaXN0YW5jZSBtZWFzdWUKZGZfdXMgJT4lIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXNlKHNvY2Rpc3RfdGlsZXMgPSBtZWFuKHNvY2Rpc3RfdGlsZXMpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9c29jZGlzdF90aWxlcykpICsgCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsYWNrIiwgZmlsbD0id2hpdGUiLCBiaW5zID0gMjAwKSArCiBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2YgbWVhbiB0aWxlcyB2aXNpdGVkIG1lYXN1cmUgYnkgY291bnR5JykKCgojIGRpc3RyaWJ1dGlvbiBvZiBtZWFuIHNkIHZpc2l0IG1lYXN1ZQpkZl91cyAlPiUgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JSAKICBzdW1tYXJpc2Uoc29jZGlzdF9zaW5nbGVfdGlsZSA9IG1lYW4oc29jZGlzdF9zaW5nbGVfdGlsZSkpICU+JQogIGdncGxvdChhZXMoeD1zb2NkaXN0X3NpbmdsZV90aWxlKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIsIGJpbnMgPSAyMDApICsKICBnZ3RpdGxlKCdEaXN0cmlidXRpb24gb2YgbWVhbiBzaW5nbGUgdGlsZSBtZWFzdXRlIGJ5IGNvdW50eScpCgoKYGBgCgojIyMgUGxvdCBwcmV2YWxlbmNlIG92ZXIgdGltZQpgYGB7cn0KCmRmX3VzICU+JSBzYW1wbGVfbigyMDAwMCkgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9cmF0ZV9kYXkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1tYXJrKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZSgiT3ZlcmFsbCBwcmV2YWxlbmNlIG92ZXIgdGltZSIpCgoKCnBlcnMgPC0gYygncGVyc19vJywgJ3BlcnNfYycsICdwZXJzX2UnLCAncGVyc19hJywgJ3BlcnNfbicpCgpmb3IgKGkgaW4gcGVycyl7CgpnZyA8LSBkZl91cyAlPiUgbXV0YXRlKHByZXZfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4wNSksIHF1YW50aWxlKC5bW2ldXSwgMC45NSksIEluZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoJ2xvd2VyIHRhaWwnLCAnY2VudGVyJywgJ3VwcGVyIHRhaWwnKSkpICU+JSAKICBmaWx0ZXIocHJldl90YWlsICE9ICdjZW50ZXInKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dGltZSwgeT1yYXRlX2RheSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPW1hcmspKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIGZhY2V0X3dyYXAofnByZXZfdGFpbCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZShpKQoKcHJpbnQoZ2cpCn0KCmBgYAoKIyMjIFBsb3Qgc29jaWFsIGRpc3RhbmNpbmcgc2luZ2xlIHRpbGUgdmlzaXRlZApgYGB7cn0KCmRmX3VzICU+JSBzYW1wbGVfbigxMDAwMCkgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPW1hcmspKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJPdmVyYWxsIHNvY2lhbCBkaXN0YW5jaW5nIChzaW5nbGUgdGlsZSkgb3ZlciB0aW1lIikKCnBlcnMgPC0gYygncGVyc19vJywgJ3BlcnNfYycsICdwZXJzX2UnLCAncGVyc19hJywgJ3BlcnNfbicpCgpmb3IgKGkgaW4gcGVycyl7CgpnZyA8LSBkZl91cyAlPiUgbXV0YXRlKGRpc3RfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4wNSksIHF1YW50aWxlKC5bW2ldXSwgMC45NSksIEluZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoJ2xvd2VyIHRhaWwnLCAnY2VudGVyJywgJ3VwcGVyIHRhaWwnKSkpICU+JSAKICBmaWx0ZXIoZGlzdF90YWlsICE9ICdjZW50ZXInKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3NpbmdsZV90aWxlKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2w9Y291bnR5X25hbWUsIHNpemU9bWFyaykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNlPVQpICsgCiAgZmFjZXRfd3JhcCh+ZGlzdF90YWlsKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKGkpCgpwcmludChnZykKfQoKYGBgCgojIyMgQ29udHJvbCBmb3Igd2Vla2VuZCBlZmZlY3QgCmBgYHtyfQoKd2Vla2VuZCA8LSBjKDYsIDcsIDEzLCAxNCwgMjAsIDIxKQoKZGZfdXNfbG9lc3MgPC0gZGZfdXMgJT4lIGZpbHRlcighdGltZSAlaW4lIHdlZWtlbmQpICU+JSAKICBzcGxpdCguJGNvdW50eV9maXBzKSAlPiUKICBtYXAofiBsb2Vzcyhzb2NkaXN0X3NpbmdsZV90aWxlIH4gdGltZSwgZGF0YSA9IC4pKSAlPiUKICBtYXAocHJlZGljdCwgMToyMykgJT4lIAogIGJpbmRfcm93cygpICU+JSAKICBnYXRoZXIoa2V5ID0gJ2NvdW50eV9maXBzJywgdmFsdWUgPSAnbG9lc3MnKSAlPiUgCiAgZ3JvdXBfYnkoY291bnR5X2ZpcHMpICU+JSAKICBtdXRhdGUodGltZSA9IHJvd19udW1iZXIoKSkKCmRmX3VzIDwtIGRmX3VzICU+JSBtZXJnZShkZl91c19sb2VzcywgYnk9YygnY291bnR5X2ZpcHMnLCAndGltZScpKSAlPiUgCiAgbXV0YXRlKHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4gPSBpZmVsc2UodGltZSAlaW4lIHdlZWtlbmQsIGxvZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSAlPiUKICBhcnJhbmdlKGNvdW50eV9maXBzLCB0aW1lKQoKZGZfdXMKCmBgYAoKYGBge3J9CgpkZl91cyAlPiUgc2FtcGxlX24oMTAwMDApICU+JQogIGdncGxvdChhZXMoeD10aW1lLCB5PXNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1jb3VudHlfbmFtZSwgc2l6ZT1tYXJrKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZSgiT3ZlcmFsbCBzb2NpYWwgZGlzdGFuY2luZyAoc2luZ2xlIHRpbGUpIG92ZXIgdGltZSIpCgpwZXJzIDwtIGMoJ3BlcnNfbycsICdwZXJzX2MnLCAncGVyc19lJywgJ3BlcnNfYScsICdwZXJzX24nKQoKZm9yIChpIGluIHBlcnMpewoKZ2cgPC0gZGZfdXMgJT4lIG11dGF0ZShkaXN0X3RhaWwgPSBjdXQoLltbaV1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygtSW5mLCBxdWFudGlsZSguW1tpXV0sIDAuMDUpLCBxdWFudGlsZSguW1tpXV0sIDAuOTUpLCBJbmYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdsb3dlciB0YWlsJywgJ2NlbnRlcicsICd1cHBlciB0YWlsJykpKSAlPiUgCiAgZmlsdGVyKGRpc3RfdGFpbCAhPSAnY2VudGVyJykgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWNvdW50eV9uYW1lLCBzaXplPW1hcmspKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIGZhY2V0X3dyYXAofmRpc3RfdGFpbCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZShpKQoKcHJpbnQoZ2cpCn0KCmBgYAoKIyMjIFZhcmlhbmNlIG92ZXIgdGltZQpgYGB7cn0KCmRmX3VzICU+JSBncm91cF9ieSh0aW1lKSAlPiUgCiAgc3VtbWFyaXplKHNvY2Rpc3RfdmFyID0gdmFyKHNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF92YXIpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdndGl0bGUoIlZhcmlhbmNlIG9mIHNvY2lhbCBkaXN0YW5jaW5nIGluZGV4IG92ZXIgdGltZSIpCgoKZGZfdXMgJT4lIGdyb3VwX2J5KHRpbWUpICU+JSAKICBzdW1tYXJpemUoc29jZGlzdF92YXIgPSB2YXIoc29jZGlzdF9zaW5nbGVfdGlsZSksCiAgICAgICAgICAgIHNvY2Rpc3RfdmFyX2NsZWFuID0gdmFyKHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pKSAlPiUgCiAgZ2dwbG90KCkgKwogICNnZW9tX2xpbmUoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3ZhcikpICsKICBnZW9tX2xpbmUoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3Zhcl9jbGVhbikpICsKICBnZ3RpdGxlKCJWYXJpYW5jZSBvZiBzbW90aGVkIHNvY2lhbCBkaXN0YW5jaW5nIGluZGV4IG92ZXIgdGltZSIpCgpgYGAKCgoKCiMjIyBDb3JyZWxhdGlvbnMgCgpgYGB7cn0KCmRmX3VzICU+JSBzZWxlY3QoLXRpbWUsIC1kYXRlLCAtY291bnR5X25hbWUpICU+JSAKICBncm91cF9ieShjb3VudHlfZmlwcykgJT4lCiAgc3VtbWFyaXplX2lmKGlzLm51bWVyaWMsIG1lYW4pICU+JSAKICBzZWxlY3QoLWNvdW50eV9maXBzKSAlPiUKICBjb3IodXNlPSdwYWlyd2lzZS5jb21wbGV0ZS5vYnMnKSAlPiUgCiAgcm91bmQoMykKICAKYGBgCgoKIyBNb2RlbCBidWlsZGluZwoKIyMgUHJlcGFyZSBmdW5jdGlvbnMKCmBgYHtyfQoKIyBmdW5jdGlvbiBjYWxjdWxhdGVzIGFsbCByZWxldmFudCBtb2RlbHMKcnVuX21vZGVscyA8LSBmdW5jdGlvbih5LCBsdmwxX3gsIGx2bDJfeCwgbHZsMl9pZCwgZGF0YSwgY3RybHM9Ril7CgogICMgc3Vic2V0IGRhdGEKICBkYXRhID0gZGF0YSAlPiUgCiAgICBkcGx5cjo6c2VsZWN0KGFsbF9vZih5KSwgYWxsX29mKGx2bDFfeCksIGFsbF9vZihsdmwyX3gpLCBhbGxfb2YobHZsMl9pZCksIAogICAgICAgICAgICAgICAgICBwb3BkZW5zLCByYXRlX2RheSwgYWxsX29mKHkpKQogIGRhdGEgPSBkYXRhICU+JSAKICAgIGRwbHlyOjpyZW5hbWUoeSA9IGFsbF9vZih5KSwKICAgICAgICAgICBsdmwxX3ggPSBhbGxfb2YobHZsMV94KSwKICAgICAgICAgICBsdmwyX3ggPSBhbGxfb2YobHZsMl94KSwKICAgICAgICAgICBsdmwyX2lkID0gYWxsX29mKGx2bDJfaWQpCiAgICAgICAgICAgKQogIAogICMgY29uZmlndXJlIG9wdGltaXphdGlvbiBwcm9jZWR1cmUKICBjdHJsX2NvbmZpZyA8LSBsbWVDb250cm9sKG9wdCA9ICdvcHRpbScsIG1heEl0ZXIgPSAxMDAsIG1zTWF4SXRlciA9IDEwMCkKCiAgIyBiYXNlbGluZQogIGJhc2VsaW5lIDwtIGxtZShmaXhlZCA9IHkgfiAxLCByYW5kb20gPSB+IDEgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCgogICMgcmFuZG9tIGludGVyY2VwdCBmaXhlZCBzbG9wZQogIHJhbmRvbV9pbnRlcmNlcHQgPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCArIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiAxIHwgbHZsMl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQoKICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgcmFuZG9tX3Nsb3BlIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKyBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKCiAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogIGludGVyYWN0aW9uIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3gsIAogICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAjIGNyZWF0ZSBsaXN0IHdpdGggcmVzdWx0cwogIHJlc3VsdHMgPC0gbGlzdCgnYmFzZWxpbmUnID0gYmFzZWxpbmUsIAogICAgICAgICAgICAgICAgICAicmFuZG9tX2ludGVyY2VwdCIgPSByYW5kb21faW50ZXJjZXB0LCAKICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZSIgPSByYW5kb21fc2xvcGUsCiAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbiIgPSBpbnRlcmFjdGlvbikKICAKICAKICBpZiAoY3RybHMgPT0gJ2RlbScgfCBjdHJscyA9PSAncHJldicpewogICAgCiAgICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgICByYW5kb21fc2xvcGVfY3RybF9kZW0gPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCArIGx2bDJfeCArIHBvcGRlbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgICBpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3ggKyBwb3BkZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQogIAogICAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogICAgaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtIDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3ggKyBsdmwxX3ggKiBwb3BkZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKSAgICAgICAgCiAgICAKICAgICMgY3JlYXRlIGxpc3Qgd2l0aCByZXN1bHRzCiAgICByZXN1bHRzIDwtIGxpc3QoJ2Jhc2VsaW5lJyA9IGJhc2VsaW5lLCAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX2ludGVyY2VwdCIgPSByYW5kb21faW50ZXJjZXB0LCAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlIiA9IHJhbmRvbV9zbG9wZSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb24iID0gaW50ZXJhY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZV9jdHJsX2RlbSIgPSByYW5kb21fc2xvcGVfY3RybF9kZW0sCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0iID0gaW50ZXJhY3Rpb25fY3RybF9tYWluX2RlbSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtIiA9IGludGVyYWN0aW9uX2N0cmxfaW50X2RlbSkKICB9CiAgCiAgaWYgKGN0cmxzID09ICdwcmV2Jyl7CiAgCiAgICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgICByYW5kb21fc2xvcGVfY3RybF9wcmV2IDwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKyBsdmwyX3ggKyBwb3BkZW5zICsgcmF0ZV9kYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94ICsgcmF0ZV9kYXkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykgIAogICAgCiAgICAgICAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogICAgaW50ZXJhY3Rpb25fY3RybF9tYWluX3ByZXYgPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCAqIGx2bDJfeCArIHBvcGRlbnMgKyByYXRlX2RheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAKICAgICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICAgIGludGVyYWN0aW9uX2N0cmxfaW50X3ByZXY8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICogbHZsMl94ICsgbHZsMV94ICogcG9wZGVucyArIHJhdGVfZGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94ICsgcmF0ZV9kYXkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgICAjIGNyZWF0ZSBsaXN0IHdpdGggcmVzdWx0cwogICAgcmVzdWx0cyA8LSBsaXN0KCdiYXNlbGluZScgPSBiYXNlbGluZSwgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9pbnRlcmNlcHQiID0gcmFuZG9tX2ludGVyY2VwdCwgCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZSIgPSByYW5kb21fc2xvcGUsCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uIiA9IGludGVyYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGVfY3RybF9kZW0iID0gcmFuZG9tX3Nsb3BlX2N0cmxfZGVtLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtIiA9IGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0sCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfaW50X2RlbSIgPSBpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW0sICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlX2N0cmxfcHJldiIgPSByYW5kb21fc2xvcGVfY3RybF9wcmV2LAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX21haW5fcHJldiIgPSBpbnRlcmFjdGlvbl9jdHJsX21haW5fcHJldiwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldiIgPSBpbnRlcmFjdGlvbl9jdHJsX2ludF9wcmV2KQogIH0KICAKICBpZihjdHJscyA9PSAnZXhwJyl7CiAgICAjIHJhbmRvbSBpbnRlcmNlcHQgcmFuZG9tIHNsb3BlCiAgcmFuZG9tX3Nsb3BlX2V4cCA8LSBsbWUoZml4ZWQgPSB5IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSArIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IChsdmwxX3ggKyBJKGx2bDFfeF4yKSkgfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKCiAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogIGludGVyYWN0aW9uX2V4cCA8LSBsbWUoZml4ZWQgPSB5IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSAqIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykgIAogIAogIAogICMgY3JlYXRlIGxpc3Qgd2l0aCByZXN1bHRzCiAgcmVzdWx0cyA8LSBsaXN0KCdiYXNlbGluZScgPSBiYXNlbGluZSwgCiAgICAgICAgICAgICAgICAgICJyYW5kb21faW50ZXJjZXB0IiA9IHJhbmRvbV9pbnRlcmNlcHQsIAogICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlIiA9IHJhbmRvbV9zbG9wZSwKICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uIiA9IGludGVyYWN0aW9uLCAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlX2V4cCIgPSByYW5kb21fc2xvcGVfZXhwLAogICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fZXhwIiA9IGludGVyYWN0aW9uX2V4cCkKICB9CiAgCiAgcmV0dXJuKHJlc3VsdHMpCiAgICAgICAgCn0KCiMgZXh0cmFjdHMgdGFibGUgd2l0aCBjb2VmZmljaWVudHMgYW5kIHRlc3RzIHN0YXRpc3RpY3MKZXh0cmFjdF9yZXN1bHRzIDwtIGZ1bmN0aW9uKG1vZGVscykgewogIAogIG1vZGVsc19zdW1tYXJ5IDwtIG1vZGVscyAlPiUgCiAgbWFwKHN1bW1hcnkpICU+JSAKICBtYXAoInRUYWJsZSIpICU+JSAKICBtYXAoYXMuZGF0YS5mcmFtZSkgJT4lIAogIG1hcChyb3VuZCwgMTApIAogICMgJT4lIG1hcCh+IC5bc3RyX2RldGVjdChyb3duYW1lcyguKSwgJ0ludGVyfGx2bCcpLF0pCiAgCiAgcmV0dXJuKG1vZGVsc19zdW1tYXJ5KQogIAp9CgoKY29tcGFyZV9tb2RlbHMgPC0gZnVuY3Rpb24obW9kZWxzKSB7CgogIG1kbF9uYW1lcyA8LSBtb2RlbHMgJT4lIG5hbWVzKCkKICAKICBzdHIgPSAnJwogIGZvciAoaSBpbiBtZGxfbmFtZXMpewogICAgCiAgICBtZGxfc3RyIDwtIHBhc3RlKCdtb2RlbHMkJywgaSwgc2VwID0gJycpCiAgICAKICAgIGlmKGkgPT0gJ2Jhc2VsaW5lJyl7CiAgICAgIHN0ciA8LSBtZGxfc3RyCiAgICB9ZWxzZXsKICAgIHN0ciA8LSBwYXN0ZShzdHIsIG1kbF9zdHIsIHNlcD0nLCAnKQogICAgfQogIH0KICAKICBhbm92YV9zdHIgPC0gcGFzdGUwKCdhbm92YSgnLCBzdHIsICcpJykKICBtZGxfY29tcCA8LSBldmFsKHBhcnNlKHRleHQ9YW5vdmFfc3RyKSkKICByb3duYW1lcyhtZGxfY29tcCkgPSBtZGxfbmFtZXMKICByZXR1cm4obWRsX2NvbXApCn0KCmBgYAoKIyMgUmVzY2FsZSBEYXRhCmBgYHtyfQoKbHZsMl9zY2FsZWQgPC0gZGZfdXMgJT4lIAogIHNlbGVjdCgtdGltZSwgLW1hcmssIC1kYXRlLCAtY291bnR5X25hbWUsIC1yYXRlX2RheSwKICAgICAgICAgLXNvY2Rpc3RfdGlsZXMsIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbiwgLWxvZXNzKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoLWNvdW50eV9maXBzKSwgc2NhbGUpCgpsdmwxX3NjYWxlZCA8LSBkZl91cyAlPiUgCiAgc2VsZWN0KGNvdW50eV9maXBzLCB0aW1lLCByYXRlX2RheSwgc29jZGlzdF9zaW5nbGVfdGlsZSwgc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikgJT4lIAogIG11dGF0ZV9hdCh2YXJzKC1jb3VudHlfZmlwcywgLXRpbWUpLCBzY2FsZSkKCmRmX3VzX3NjYWxlZCA8LSBwbHlyOjpqb2luKGx2bDFfc2NhbGVkLCBsdmwyX3NjYWxlZCwgYnkgPSAnY291bnR5X2ZpcHMnKQoKZGZfdXNfc2NhbGVkCmBgYAoKCiMjIFByZWRpY3QgcHJldmFsZW5jZQojIyMgcHJldmFsZW5jZSB+IG9wZW5uZXNzCmBgYHtyfQoKbW9kZWxzX29fY292aWQgPC1ydW5fbW9kZWxzKHkgPSAncmF0ZV9kYXknLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfbycsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19vX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX29fY292aWQpCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9Cgptb2RlbHNfY19jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19jX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2NfY292aWQpCgoKYGBgCgojIyMgcHJldmFsZW5jZSB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCm1vZGVsc19lX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2VfY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfZV9jb3ZpZCkKCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCm1vZGVsc19hX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfYScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdjb3VudHlfZmlwcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2FfY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfYV9jb3ZpZCkKCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gbmV1cm90aWNpc20KYGBge3J9Cgptb2RlbHNfbl9jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19uX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX25fY292aWQpCgoKYGBgCgoKIyMgUHJlZGljdCBzb2NpYWwgZGlzdGFuY2luZwojIyMgc29jaWFsIGRpc3RhbmNpbmcgfiBvcGVubmVzcwpgYGB7cn0KCm1vZGVsc19vX3NkIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19vJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAncHJldicpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX29fc2QpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfb19zZCkKCgpgYGAKCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKbW9kZWxzX2Nfc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfY19zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19jX3NkKQoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKbW9kZWxzX2Vfc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2UnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfZV9zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19lX3NkKQoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCm1vZGVsc19hX3NkIDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19hJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2NvdW50eV9maXBzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAncHJldicpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2Ffc2QpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfYV9zZCkKCgpgYGAKCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IG5ldXJvdGljaXNtCmBgYHtyfQoKbW9kZWxzX25fc2QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAnY291bnR5X2ZpcHMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfbl9zZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19uX3NkKQoKYGBgCgoKIyMgQ3JlYXRlIG92ZXJ2aWV3IHRhYmxlIAoKIyMjIERlZmluZSBmdW5jdGlvbiB0byBjcmVhdGUgb3ZlcnZpZXcgdGFibGVzCmBgYHtyfQoKc3VtbWFyeV90YWJsZSA8LSBmdW5jdGlvbihtb2RlbHMsIGR2X25hbWUsIHByZXY9Ril7CgogIHRlbXBfZGZfY3RybF9tYWluIDwtIE5VTEwKICB0ZW1wX2RmX2N0cmxfaW50IDwtIE5VTEwKICB0ZW1wX2RmX2N0cmxfaW50X3ByZXYgPC0gTlVMTAogIAogIGZvciAoaSBpbiBtb2RlbHMpewogICAgcmVzdWx0cyA8LSBpICU+JSBleHRyYWN0X3Jlc3VsdHMoKQogICAgCiAgICByZXN1bHRzX2N0cmxfbWFpbiA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW1bJ2x2bDFfeDpsdmwyX3gnLF0KICAgIHRlbXBfZGZfY3RybF9tYWluIDwtIHRlbXBfZGZfY3RybF9tYWluICU+JSByYmluZChyZXN1bHRzX2N0cmxfbWFpbikKICAgIAogICAgcmVzdWx0c19jdHJsX2ludCA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfaW50X2RlbVsnbHZsMV94Omx2bDJfeCcsXQogICAgdGVtcF9kZl9jdHJsX2ludCA8LSB0ZW1wX2RmX2N0cmxfaW50ICU+JSByYmluZChyZXN1bHRzX2N0cmxfaW50KQogICAgCiAgICBpZihwcmV2KXsKICAgICAgcmVzdWx0c19jdHJsX2ludF9wcmV2IDwtIHJlc3VsdHMkaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldlsnbHZsMV94Omx2bDJfeCcsXQogICAgICB0ZW1wX2RmX2N0cmxfaW50X3ByZXYgPC0gdGVtcF9kZl9jdHJsX2ludF9wcmV2ICU+JSByYmluZChyZXN1bHRzX2N0cmxfaW50X3ByZXYpCiAgICB9CiAgICAgICAgCiAgfQogIAogIG5hbWVzX2N0cmxfbWFpbiA8LSBwYXN0ZTAoZHZfbmFtZSwgJ34nLCBjKCdvJywgJ2MnLCAnZScsICdhJywgJ24nKSwgJyp0aW1lJywgJ19jcnRsX3BvcGRlbnMnKQogIHJvd25hbWVzKHRlbXBfZGZfY3RybF9tYWluKSA8LSBuYW1lc19jdHJsX21haW4KCiAgbmFtZXNfY3RybF9pbnQgPC0gcGFzdGUwKGR2X25hbWUsICd+JywgYygnbycsICdjJywgJ2UnLCAnYScsICduJyksICcqdGltZScsICdfY3J0bF9wb3BkZW5zKnRpbWUnKQogIHJvd25hbWVzKHRlbXBfZGZfY3RybF9pbnQpIDwtIG5hbWVzX2N0cmxfaW50CgogIGlmKHByZXYpewogICAgbmFtZXNfY3RybF9pbnRfcHJldiA8LSBwYXN0ZTAoZHZfbmFtZSwgJ34nLCBjKCdvJywgJ2MnLCAnZScsICdhJywgJ24nKSwgJyp0aW1lJywgJ19jcnRsX3BvcGRlbnMqdGltZV9wcmV2JykKICAgIHJvd25hbWVzKHRlbXBfZGZfY3RybF9pbnRfcHJldikgPC0gbmFtZXNfY3RybF9pbnRfcHJldgogICAgCiAgICBzdW1fdGFiIDwtIHJiaW5kKHRlbXBfZGZfY3RybF9tYWluLCB0ZW1wX2RmX2N0cmxfaW50LCB0ZW1wX2RmX2N0cmxfaW50X3ByZXYpICU+JSByb3VuZCg0KQogIH1lbHNlewogICAgc3VtX3RhYiA8LSByYmluZCh0ZW1wX2RmX2N0cmxfbWFpbiwgdGVtcF9kZl9jdHJsX2ludCkgJT4lIHJvdW5kKDQpCiAgfQoKCiAgCiAgcmV0dXJuKHN1bV90YWIpCgp9IAoKYGBgCgojIyMgQ3JlYXRlIG92ZXJ2aWV3IHRhYmxlcwpgYGB7cn0KIyBwcmV2YWxlbmNlCm1vZGVsc19wcmV2IDwtIGxpc3QobW9kZWxzX29fY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX2NvdmlkLCAKICAgICAgICAgICAgICAgICAgICBtb2RlbHNfZV9jb3ZpZCwgCiAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2FfY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX2NvdmlkKQoKc3VtX3RhYl9wcmV2IDwtIHN1bW1hcnlfdGFibGUobW9kZWxzX3ByZXYsIGR2X25hbWUgPSAncHJldicpCgp3cml0ZS50YWJsZShzdW1fdGFiX3ByZXYsIHF1b3RlPUYpCgojIHNvY2lhbCBkaXN0YW5jaW5nCm1vZGVsc19zb2NkaXN0IDwtIGxpc3QobW9kZWxzX29fc2QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX3NkLCAKICAgICAgICAgICAgICAgICAgICAgICBtb2RlbHNfZV9zZCwgCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2Ffc2QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX3NkKQoKc3VtX3RhYl9zb2NkaXN0IDwtIHN1bW1hcnlfdGFibGUobW9kZWxzX3NvY2Rpc3QsIGR2X25hbWUgPSAnc29jZGlzdCcsIHByZXY9VCkKCndyaXRlLnRhYmxlKHN1bV90YWJfc29jZGlzdCwgcXVvdGU9RikKCgpgYGAKCgoKCiMgQ29uZGl0aW9uYWwgcmFuZG9tIGZvcmVzdCBhbmFseXNpcyAKCiMjIyBFeHRyYWN0IHNsb3BlcwpgYGB7cn0KCiMgc2xvcGUgcHJldmFsZW5jZQpkZl91c19zbG9wZV9wcmV2IDwtIGRmX3VzX3NjYWxlZCAlPiUgc3BsaXQoLiRjb3VudHkpICU+JSAKICBtYXAofiBsbShyYXRlX2RheSB+IHRpbWUsIGRhdGEgPSAuKSkgJT4lCiAgbWFwKGNvZWYpICU+JSAKICBtYXBfZGJsKCd0aW1lJykgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpICU+JSAKICByZW5hbWUoc2xvcGVfcHJldiA9ICcuJykKCmRmX3VzX3Nsb3BlX3ByZXYgPC0gZGZfdXNfc2NhbGVkICU+JSBzZWxlY3QoLXRpbWUsIC1yYXRlX2RheSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZShjb3VudHlfZmlwcyA9IGFzLmNoYXJhY3Rlcihjb3VudHlfZmlwcykpICU+JQogIGlubmVyX2pvaW4oZGZfdXNfc2xvcGVfcHJldiwgYnkgPSAnY291bnR5X2ZpcHMnKSAlPiUKICBkcm9wX25hKCkKCgoKIyBzbG9wZSBzb2NpYWwgZGlzdGFuY2luZwpkZl91c19zbG9wZV9zb2NkaXN0IDwtIGRmX3VzX3NjYWxlZCAlPiUgc3BsaXQoLiRjb3VudHkpICU+JSAKICBtYXAofiBsbShzb2NkaXN0X3NpbmdsZV90aWxlIH4gdGltZSwgZGF0YSA9IC4pKSAlPiUKICBtYXAoY29lZikgJT4lIAogIG1hcF9kYmwoJ3RpbWUnKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykgJT4lIAogIHJlbmFtZShzbG9wZV9zb2NkaXN0ID0gJy4nKQoKZGZfdXNfc2xvcGVfc29jZGlzdCA8LSBkZl91c19zY2FsZWQgJT4lIHNlbGVjdCgtdGltZSwgLXJhdGVfZGF5LCAtc29jZGlzdF9zaW5nbGVfdGlsZSkgJT4lCiAgZGlzdGluY3QoKSAlPiUgCiAgbXV0YXRlKGNvdW50eV9maXBzID0gYXMuY2hhcmFjdGVyKGNvdW50eV9maXBzKSkgJT4lCiAgaW5uZXJfam9pbihkZl91c19zbG9wZV9zb2NkaXN0LCBieSA9ICdjb3VudHlfZmlwcycpICU+JQogIGRyb3BfbmEoKQoKZGZfdXNfc2xvcGVfc29jZGlzdApgYGAKCiMjIyBFeHBsb3JlIGRpc3RyaWJ1dGlvbiBvZiBzbG9wZXMKYGBge3J9CmRmX3VzX3Nsb3BlX3ByZXYgJT4lIGdncGxvdChhZXMoc2xvcGVfcHJldikpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCkKCmRmX3VzX3Nsb3BlX3NvY2Rpc3QgJT4lIGdncGxvdChhZXMoc2xvcGVfc29jZGlzdCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCkKCmBgYAoKIyBDUkYgcHJldmFsZW5jZSB+IG9wZW5uZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9vX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfbyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfb192YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX29fZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX29fdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX29fZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX29fdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX29fdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgcHJldmFsZW5jZSB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9jX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfYyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfY192YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2NfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBwcmV2YWxlbmNlIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9lX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfZSArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfZV92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2VfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2VfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2VfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2VfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2VfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBwcmV2YWxlbmNlIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfYV9maXRfcHJldiA8LSBjZm9yZXN0KHNsb3BlX3ByZXYgfiBwZXJzX2EgKyBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl91c19zbG9wZV9wcmV2Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2FfdmFyaW1wX3ByZXYgPC0gdmFyaW1wKGNyZl9hX2ZpdF9wcmV2LCBucGVybSA9IDEpCmNyZl9hX3ZhcmltcF9jb25kX3ByZXYgPC0gdmFyaW1wKGNyZl9hX2ZpdF9wcmV2LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9hX3ZhcmltcF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9hX3ZhcmltcF9jb25kX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgoKIyBDUkYgcHJldmFsZW5jZSB+IG5ldXJvdGljaXNtCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9uX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfbiArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IG9wZW5uZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9vX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfbyArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfb192YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX29fZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX29fdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX29fZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX29fdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX29fdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMgQ1JGIHNvY2lhbCBkaXN0YW5jaW5nIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2NfZml0X3NvY2Rpc3QgPC0gY2ZvcmVzdChzbG9wZV9zb2NkaXN0IH4gcGVyc19jICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9jX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfY19maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfY192YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfY19maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfY192YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfY192YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBleHRyYXZlcnNpb24KYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2VfZml0X3NvY2Rpc3QgPC0gY2ZvcmVzdChzbG9wZV9zb2NkaXN0IH4gcGVyc19lICsgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKwogICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfdXNfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9lX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfZV9maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfZV92YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfZV9maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfZV92YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfZV92YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9hX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfYSArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfYV92YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX2FfZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX2FfdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX2FfZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2FfdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2FfdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IG5ldXJvdGljaXNtCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9uX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfbiArIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsKICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX3VzX3Nsb3BlX3NvY2Rpc3RbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfc29jZGlzdCA8LSB2YXJpbXAoY3JmX25fZml0X3NvY2Rpc3QsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfc29jZGlzdCA8LSB2YXJpbXAoY3JmX25fZml0X3NvY2Rpc3QsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCiMgTGluZWFyIG1vZGVscyBwcmVkaWN0aW5nIHNsb3BlcyBmcm9tIHBlcnNvbmFsaXR5CmBgYHtyfQoKbG1fc2xvcGVfcHJldl9wZXJzIDwtIGxtKHNsb3BlX3ByZXYgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3Nsb3BlX3ByZXYpCmxtX3Nsb3BlX3ByZXZfcGVycyAlPiUgc3VtbWFyeSgpCgoKbG1fc2xvcGVfc29jZGlzdF9wZXJzIDwtIGxtKHNsb3BlX3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX3Nsb3BlX3NvY2Rpc3QpCmxtX3Nsb3BlX3NvY2Rpc3RfcGVycyAlPiUgc3VtbWFyeSgpCgpgYGAKCiMgTGluZWFyIG1vZGVscyBwcmVkaWN0aW5nIHNsb3BlcyB3aXRoIGNvbnRyb2xzCmBgYHtyfQoKbG1fc2xvcGVfcHJldl9wZXJzIDwtIGxtKHNsb3BlX3ByZXYgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24gKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydF9kaXN0YW5jZSArIHJlcHVibGljYW4gKyBtZWRhZ2UgKyBtYWxlICsgcG9wZGVucyArIAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYW51ZmFjdCArIHRvdXJpc20gKyBhY2FkZW1pY3MgKyBtZWRpbmMgKyBwaHlzaWNpYW5fcGMsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfc2xvcGVfcHJldikKbG1fc2xvcGVfcHJldl9wZXJzICU+JSBzdW1tYXJ5KCkKCgpsbV9zbG9wZV9zb2NkaXN0X3BlcnMgPC0gbG0oc2xvcGVfc29jZGlzdCB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbnVmYWN0ICsgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19zbG9wZV9zb2NkaXN0KQpsbV9zbG9wZV9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgoKYGBge3J9CmxpYnJhcnkodGlncmlzKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCgptZSA8LSBjb3VudGllcyhjYiA9IFRSVUUpCm1lX21hcCA8LSBmb3J0aWZ5KG1lKQpwbG90KG1lX21hcCkKCm1lX21hcCAlPiUgaGVhZCgpCm1lICU+JSBoZWFkKCkKCmdnIDwtIGdncGxvdCgpCmdnIDwtIGdnICsgZ2VvbV9tYXAoZGF0YT11c19tYXBfc2hhcGUsIG1hcD11c19tYXBfc2hhcGUsCiAgICAgICAgICAgICAgICAgICAgYWVzKCB4ID0geCwgeSA9IHksIG1hcF9pZD1maXBzKSwKICAgICAgICAgICAgICAgICAgICBjb2xvcj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIsIHNpemU9MC4yNSkKZ2cgPC0gZ2cgKyBjb29yZF9tYXAoKQpnZyA8LSBnZyArIHRoZW1lX21hcCgpCmdnCmBgYAoKYGBge3J9CmRmX3VzX2NvdmlkICU+JSBmaWx0ZXIoY291bnR5ID09IDIzMDEzKQoKYGBgCgoKYGBge3J9CgpsaWJyYXJ5KHVzbWFwKQpsaWJyYXJ5KGdncGxvdDIpCgp1c19tYXBfc2hhcGUgPSB1c19tYXAocmVnaW9ucyA9ICdjb3VudGllcycpCgp1c19tYXBfc2hhcGUKCnBsb3RfdXNtYXAoZGF0YSA9IHVzX21hcF9zaGFwZSkgKyAKICBsYWJzKHRpdGxlID0gIlVTIENvdW50aWVzIiwKICAgICAgIHN1YnRpdGxlID0gIlRoaXMgaXMgYSBibGFuayBtYXAgb2YgdGhlIGNvdW50aWVzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiIpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSAibGlnaHRibHVlIikpCmBgYAoKIyBDaGFuZ2UgcG9pbnQgYW5hbHlzaXMKCmBgYHtyfQpsaWJyYXJ5KGNoYW5nZXBvaW50KQpgYGAKCiMjIyBQcmVwYXJhdGlvbgpgYGB7cn0KIyBrZWVwIG9ubHkgY291bnRpZXMgd2l0aCBmdWxsIGRhdGEKZmlwc19jb21wbGV0ZSA8LSBkZl91c19zY2FsZWQgJT4lIAogIGdyb3VwX2J5KGNvdW50eV9maXBzKSAlPiUgCiAgc3VtbWFyaXplKG4gPSBuKCkpICU+JSAKICBmaWx0ZXIobj09bWF4KC4kbikpICU+JSAKICAuJGNvdW50eV9maXBzCmBgYAoKCmBgYHtyfQpkZl91c19zY2FsZWQKYGBgCgoKIyMjIFByZXZhbGVuY2UKYGBge3J9CgojIHJ1biBjaGFuZ2Vwb2ludCBhbmFseXNpcwpkZl91c19wcmV2X2NwdF9yZXN1bHRzIDwtIGRmX3VzX3NjYWxlZCAlPiUgc2VsZWN0KGNvdW50eV9maXBzLCByYXRlX2RheSkgJT4lCiAgZmlsdGVyKGNvdW50eV9maXBzICVpbiUgZmlwc19jb21wbGV0ZSkgJT4lIAogIHNwbGl0KC4kY291bnR5X2ZpcHMpICU+JQogIG1hcCh+IGNwdC5tZWFudmFyKGFzLnZlY3RvciguJHJhdGVfZGF5KSwKICAgICAgICAgICAgICAgICAgICBjbGFzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIHBhcmFtLmVzdGltYXRlcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIFE9MSkpCgojIGNhbGN1bGF0ZSBjaGFuZ2UgcG9pbnQKZGZfdXNfcHJldl9jcHRfZGF5IDwtIGRmX3VzX3ByZXZfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChjcHRzKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKGNwdF9kYXlfcHJldiA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpCgojIGNhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCmRmX3VzX3ByZXZfY3B0X21lYW5fZGlmZiA8LSBkZl91c19wcmV2X2NwdF9yZXN1bHRzICU+JSAKICBtYXAocGFyYW0uZXN0KSAlPiUgCiAgbWFwKH4gLiRtZWFuKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKG1lYW5fZGlmZl9wcmV2ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykKCiMgY2FsY3VsYXRlIHZhcmFpbmNlIGRpZmZlcmVuY2VzCmRmX3VzX3ByZXZfY3B0X3Zhcl9kaWZmIDwtIGRmX3VzX3ByZXZfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJHZhcmlhbmNlKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKHZhcl9kaWZmX3ByZXYgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbignY291bnR5X2ZpcHMnKQoKIyBtZXJnZSBuZXcgdmFyaWFibGVzIApkZl91c19jcHRfcHJldiA8LSBkZl91c19zY2FsZWQgJT4lCiAgc2VsZWN0KC10aW1lLCAtcmF0ZV9kYXksIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtc29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBtdXRhdGUoY291bnR5X2ZpcHMgPSBhcy5jaGFyYWN0ZXIoY291bnR5X2ZpcHMpKSAlPiUKICBsZWZ0X2pvaW4oZGZfdXNfcHJldl9jcHRfZGF5LCBieT0nY291bnR5X2ZpcHMnKSAlPiUKICBsZWZ0X2pvaW4oZGZfdXNfcHJldl9jcHRfbWVhbl9kaWZmLCBieT0nY291bnR5X2ZpcHMnKSAlPiUKICBsZWZ0X2pvaW4oZGZfdXNfcHJldl9jcHRfdmFyX2RpZmYsIGJ5PSdjb3VudHlfZmlwcycpCgpkZl91c19jcHRfcHJldiAlPiUgc2VsZWN0KGNwdF9kYXlfcHJldikgJT4lIG1hcChoaXN0KQpkZl91c19jcHRfcHJldiAlPiUgc2VsZWN0KG1lYW5fZGlmZl9wcmV2KSAlPiUgbWFwKGhpc3QpCmRmX3VzX2NwdF9wcmV2ICU+JSBzZWxlY3QodmFyX2RpZmZfcHJldikgJT4lIG1hcChoaXN0KQoKZGZfdXNfY3B0X3ByZXYgJT4lIGRpbSgpCmRmX3VzX2NwdF9wcmV2ICU+JSBkcm9wX25hKCkgJT4lIGRpbSgpCgpgYGAKCgpgYGB7cn0KCmZvcihpIGluIGhlYWQoZGZfdXNfcHJldl9jcHRfcmVzdWx0cywxOCkpewogIHBsb3QoaSkKfQoKYGBgCgojIyMgU29jZGlzdApgYGB7cn0KCiMgcnVuIGNoYW5nZXBvaW50IGFuYWx5c2lzCmRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgPC0gZGZfdXNfc2NhbGVkICU+JSBzZWxlY3QoY291bnR5X2ZpcHMsIHNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pICU+JQogIGZpbHRlcihjb3VudHlfZmlwcyAlaW4lIGZpcHNfY29tcGxldGUpICU+JSAKICBzcGxpdCguJGNvdW50eV9maXBzKSAlPiUKICBtYXAofiBjcHQubWVhbnZhcihhcy52ZWN0b3IoLiRzb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuKSwKICAgICAgICAgICAgICAgICAgICAjcGVuYWx0eSA9ICdBc3ltcHRvdGljJywKICAgICAgICAgICAgICAgICAgICBjbGFzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIHBhcmFtLmVzdGltYXRlcz1UUlVFLAogICAgICAgICAgICAgICAgICAgIFE9MSwKICAgICAgICAgICAgICAgICAgICB0ZXN0LnN0YXQgPSAnTm9ybWFsJykpCgojIGNhbGN1bGF0ZSBjaGFuZ2UgcG9pbnQKZGZfdXNfc29jZGlzdF9jcHRfZGF5IDwtIGRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChjcHRzKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKGNwdF9kYXlfc29jZGlzdCA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdjb3VudHlfZmlwcycpCgojIGNhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCmRmX3VzX3NvY2Rpc3RfY3B0X21lYW5fZGlmZiA8LSBkZl91c19zb2NkaXN0X2NwdF9yZXN1bHRzICU+JSAKICBtYXAocGFyYW0uZXN0KSAlPiUgCiAgbWFwKH4gLiRtZWFuKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKG1lYW5fZGlmZl9zb2NkaXN0ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2NvdW50eV9maXBzJykKCiMgY2FsY3VsYXRlIHZhcmFpbmNlIGRpZmZlcmVuY2VzCmRmX3VzX3NvY2Rpc3RfY3B0X3Zhcl9kaWZmIDwtIGRmX3VzX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJHZhcmlhbmNlKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKHZhcl9kaWZmX3NvY2Rpc3QgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbignY291bnR5X2ZpcHMnKQoKIyBtZXJnZSBuZXcgdmFyaWFibGVzIApkZl91c19jcHRfcHJldl9zb2NkaXN0IDwtIGRmX3VzX2NwdF9wcmV2ICU+JQogIGxlZnRfam9pbihkZl91c19zb2NkaXN0X2NwdF9kYXksIGJ5PSdjb3VudHlfZmlwcycpICU+JQogIGxlZnRfam9pbihkZl91c19zb2NkaXN0X2NwdF9tZWFuX2RpZmYsIGJ5PSdjb3VudHlfZmlwcycpICU+JQogIGxlZnRfam9pbihkZl91c19zb2NkaXN0X2NwdF92YXJfZGlmZiwgYnk9J2NvdW50eV9maXBzJykKCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIHNlbGVjdChjcHRfZGF5X3NvY2Rpc3QpICU+JSBtYXAoaGlzdCkKZGZfdXNfY3B0X3ByZXZfc29jZGlzdCAlPiUgc2VsZWN0KG1lYW5fZGlmZl9zb2NkaXN0KSAlPiUgbWFwKGhpc3QpCmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIHNlbGVjdCh2YXJfZGlmZl9zb2NkaXN0KSAlPiUgbWFwKGhpc3QpCgpkZl91c19jcHRfcHJldl9zb2NkaXN0ICU+JSBkaW0oKQpkZl91c19jcHRfcHJldl9zb2NkaXN0ICU+JSBkcm9wX25hKCkgJT4lIGRpbSgpCgpgYGAKCmBgYHtyfQoKZm9yKGkgaW4gaGVhZChkZl91c19zb2NkaXN0X2NwdF9yZXN1bHRzLDE4KSl7CiAgcGxvdChpKQp9CgpgYGAKYGBge3J9CmRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QKYGBgCgojIFByZWRpY3RpbmcgY2hhbmdlIHBvaW50cyAKIyMjIExpbmVhciBtb2RlbHMgcHJlZGljdGluZyBjaGFuZ2UgcG9pbnRzIChubyBjb250cm9scykKYGBge3J9CgpsbV9jcHJfcHJldl9wZXJzIDwtIGxtKGNwdF9kYXlfcHJldiB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfdXNfY3B0X3ByZXZfc29jZGlzdCkKbG1fY3ByX3ByZXZfcGVycyAlPiUgc3VtbWFyeSgpCgoKbG1fY3B0X3NvY2Rpc3RfcGVycyA8LSBsbShjcHRfZGF5X3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgojIExpbmVhciBtb2RlbHMgcHJlZGljdGluZyBjaGFuZ2UgcG9pbnRzIHdpdGggY29udHJvbHMKYGBge3J9CgpsbV9jcHRfcHJldl9wZXJzIDwtIGxtKGNwdF9kYXlfcHJldiB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiArIAogICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0X2Rpc3RhbmNlICsgcmVwdWJsaWNhbiArIG1lZGFnZSArIG1hbGUgKyBwb3BkZW5zICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbnVmYWN0ICsgdG91cmlzbSArIGFjYWRlbWljcyArIG1lZGluYyArIHBoeXNpY2lhbl9wYywKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl91c19jcHRfcHJldl9zb2NkaXN0KQpsbV9jcHRfcHJldl9wZXJzICU+JSBzdW1tYXJ5KCkKCmxtX2NwdF9zb2NkaXN0X3BlcnMgPC0gbG0oY3B0X2RheV9zb2NkaXN0IH4gcGVyc19vICsgcGVyc19jICsgcGVyc19lICsgcGVyc19hICsgcGVyc19uICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnRfZGlzdGFuY2UgKyByZXB1YmxpY2FuICsgbWVkYWdlICsgbWFsZSArIHBvcGRlbnMgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFudWZhY3QgKyB0b3VyaXNtICsgYWNhZGVtaWNzICsgbWVkaW5jICsgcGh5c2ljaWFuX3BjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3VzX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgoK